package net.goutalk.glcs.module.erpModel.caseErpCustomer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import net.goutalk.glcs.common.constant.GlobalConstant;
import net.goutalk.glcs.common.model.result.R;
import net.goutalk.glcs.common.page.PageOutput;
import net.goutalk.glcs.common.utils.RedisUtil;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.dto.CaseErpCustomerGatherDto;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.entity.CaseErpCustomerGather;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.entity.CaseErpCustomerGatherDetail;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.mapper.CaseErpCustomerGatherMapper;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.service.ICaseErpCustomerGatherDetailService;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.service.ICaseErpCustomerGatherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.vo.CaseErpCustomerGatherDetailInfoVo;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.vo.CaseErpCustomerGatherDetailVo;
import net.goutalk.glcs.module.erpModel.caseErpCustomer.vo.CaseErpCustomerGatherPageVo;
import net.goutalk.glcs.module.organization.entity.User;
import net.goutalk.glcs.module.workflow.utils.WorkFlowUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户回款【case_erp_customer_gather】 服务实现类
 * </p>
 *
 * @author hnyyzy
 * @since 2023-07-12
 */
@Service
@AllArgsConstructor
public class CaseErpCustomerGatherServiceImpl extends ServiceImpl<CaseErpCustomerGatherMapper, CaseErpCustomerGather> implements ICaseErpCustomerGatherService {

    private final ICaseErpCustomerGatherDetailService caseErpCustomerGatherDetailService;

    private RedisUtil redisUtil;

    @Override
    public CaseErpCustomerGatherDetailInfoVo gatherDetailInfo(Long id) {
        CaseErpCustomerGather caseErpCustomerGather = this.getById(id);
        if (caseErpCustomerGather == null) {
            R.error("找不到此客户回款信息！");
        }
        CaseErpCustomerGatherDetailInfoVo caseErpCustomerGatherDetailInfoVo = BeanUtil.toBean(caseErpCustomerGather, CaseErpCustomerGatherDetailInfoVo.class);
        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        if (StrUtil.isNotBlank(caseErpCustomerGather.getPrincipalIds())) {
            List<Long> ids = Arrays.stream(caseErpCustomerGather.getPrincipalIds().split(StringPool.COMMA)).map(Convert::toLong).collect(Collectors.toList());
            List<String> names = allUser.stream().filter(x -> ids.contains(x.getId())).map(User::getName).collect(Collectors.toList());
            caseErpCustomerGatherDetailInfoVo.setPrincipalNames(StrUtil.join(StringPool.COMMA, names));
        }
        if (ObjectUtil.isNotEmpty(caseErpCustomerGather.getCreateUserId())) {
            User user = allUser.stream().filter(x -> x.getId().equals(caseErpCustomerGather.getCreateUserId())).findFirst().orElse(new User());
            if (StrUtil.isNotBlank(user.getName())) {
                caseErpCustomerGatherDetailInfoVo.setCreateUserName(user.getName());
            }
        }
        User user = allUser.stream().filter(x -> ObjectUtil.isNotEmpty(caseErpCustomerGather.getCreateUserId()) && x.getId().equals(caseErpCustomerGather.getCreateUserId())).findFirst().orElse(new User());
        if (StrUtil.isNotBlank(user.getName())) {
            caseErpCustomerGatherDetailInfoVo.setCreateUserName(user.getName());
        }
        List<CaseErpCustomerGatherDetail> list = caseErpCustomerGatherDetailService.list(Wrappers.<CaseErpCustomerGatherDetail>query().lambda()
                .eq(CaseErpCustomerGatherDetail::getGatherId, id).orderByDesc(CaseErpCustomerGatherDetail::getCreateDate));
        List<CaseErpCustomerGatherDetailVo> caseErpCustomerGatherDetailVos = BeanUtil.copyToList(list, CaseErpCustomerGatherDetailVo.class);
        for (CaseErpCustomerGatherDetailVo caseErpCustomerGatherDetailVo : caseErpCustomerGatherDetailVos) {
            if (ObjectUtil.isNotEmpty(caseErpCustomerGatherDetailVo.getCreateUserId())) {
                User user1 = allUser.stream().filter(x -> x.getId().equals(caseErpCustomerGatherDetailVo.getCreateUserId())).findFirst().orElse(new User());
                if (StrUtil.isNotBlank(user1.getName())) {
                    caseErpCustomerGatherDetailVo.setCreateUserName(user1.getName());
                }
            }
        }
        caseErpCustomerGatherDetailInfoVo.setCaseErpCustomerGatherDetailVoList(caseErpCustomerGatherDetailVos);
        return caseErpCustomerGatherDetailInfoVo;
    }

    @Override
    public PageOutput<CaseErpCustomerGatherPageVo> getPageList(CaseErpCustomerGatherDto dto) {
        if (ObjectUtil.isNotNull(dto.getReceivedStartTime()) && ObjectUtil.isNotNull(dto.getReceivedEndTime())) {
            dto.setReceivedStartTime(WorkFlowUtil.getStartOfDay(dto.getReceivedStartTime()));
            dto.setReceivedEndTime(WorkFlowUtil.getEndOfDay(dto.getReceivedEndTime()));
        }
        if (ObjectUtil.isNotNull(dto.getFinallyStartTime()) && ObjectUtil.isNotNull(dto.getFinallyEndTime())) {
            dto.setFinallyStartTime(WorkFlowUtil.getStartOfDay(dto.getFinallyStartTime()));
            dto.setFinallyEndTime(WorkFlowUtil.getEndOfDay(dto.getFinallyEndTime()));
        }
        List<CaseErpCustomerGather> list = this.list(Wrappers.<CaseErpCustomerGather>query().lambda()
                .like(StrUtil.isNotBlank(dto.getKeyword()), CaseErpCustomerGather::getName, dto.getKeyword())
                        .orderByDesc(CaseErpCustomerGather::getCreateDate)
                .between(ObjectUtil.isNotNull(dto.getFinallyStartTime()) && ObjectUtil.isNotNull(dto.getFinallyEndTime())
                        , CaseErpCustomerGather::getFinallyDate, dto.getFinallyStartTime(), dto.getFinallyEndTime())
                .between(ObjectUtil.isNotNull(dto.getReceivedStartTime()) && ObjectUtil.isNotNull(dto.getReceivedEndTime())
                        , CaseErpCustomerGather::getReceivedDate, dto.getReceivedStartTime(), dto.getReceivedEndTime())
        );
        List<CaseErpCustomerGatherPageVo> caseErpCustomerGatherPageVoList = BeanUtil.copyToList(list, CaseErpCustomerGatherPageVo.class);

        List<Long> gatherIdList = caseErpCustomerGatherDetailService.list().stream().map(x -> x.getGatherId()).collect(Collectors.toList());

        List<User> allUser = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
        });
        for (CaseErpCustomerGatherPageVo caseErpCustomerGatherPageVo : caseErpCustomerGatherPageVoList) {
            if (ObjectUtil.isNotEmpty(caseErpCustomerGatherPageVo.getCreateUserId())){
                User user = allUser.stream().filter(x -> x.getId().equals(caseErpCustomerGatherPageVo.getCreateUserId())).findFirst().orElse(new User());
                if (StrUtil.isNotBlank(user.getName())){
                    caseErpCustomerGatherPageVo.setCreateUserName(user.getName());
                }
            }
            if (ObjectUtil.isNotEmpty(caseErpCustomerGatherPageVo.getUnpaidAmount()) && BigDecimal.ZERO.compareTo(caseErpCustomerGatherPageVo.getUnpaidAmount()) == 0){//已完成
                caseErpCustomerGatherPageVo.setState(1);//已完成
                caseErpCustomerGatherPageVo.setOverDay(0L);
            }else {
                //逾期天数：今天-计划回款时间
                LocalDateTime now = LocalDateTime.now();
                if (gatherIdList.contains(caseErpCustomerGatherPageVo.getId()) || now.isAfter(caseErpCustomerGatherPageVo.getReceivedDate())) {
                    caseErpCustomerGatherPageVo.setState(0);//进行中
                } else {
                    caseErpCustomerGatherPageVo.setState(-1);//未开始
                }

                if (caseErpCustomerGatherPageVo.getAlreadyAmount() == null) {
                    caseErpCustomerGatherPageVo.setAlreadyAmount(BigDecimal.ZERO);
                }
                if (caseErpCustomerGatherPageVo.getUnpaidAmount() == null) {
                    caseErpCustomerGatherPageVo.setUnpaidAmount(BigDecimal.ZERO);
                }
                // 逾期天数
                if (now.isAfter(caseErpCustomerGatherPageVo.getFinallyDate())) {
                    long between = Duration.between(caseErpCustomerGatherPageVo.getFinallyDate(), LocalDateTime.now()).toDays();
                    caseErpCustomerGatherPageVo.setOverDay(between);
                } else {
                    caseErpCustomerGatherPageVo.setOverDay(0L);
                }
            }
        }
        PageOutput<CaseErpCustomerGatherPageVo> output = new PageOutput<>();
        output.setCurrentPage(dto.getLimit());
        output.setPageSize(dto.getSize());
        output.setTotal(list.size());
        output.setList(caseErpCustomerGatherPageVoList);
        return output;
    }
}
